package 遍历器;

import 抽象语法树节点.*;
import 抽象语法树节点.后缀表达式.*;
import 抽象语法树节点.字面量类.*;
import 抽象语法树节点.表达式类.*;
import 抽象语法树节点.语句类.条件语句;
import 抽象语法树节点.语句类.赋值语句;
import 抽象语法树节点.语句类.返回语句;

public class 抽象语法树基础遍历器 {

    public void 遍历(抽象语法树基础监听器 监听器, 抽象语法树 节点) {
        if (节点 == null) return;

        监听器.进入抽象语法树(节点);

        if (节点 instanceof 代码块 代码块) {
            遍历代码块(监听器, 代码块);
        } else if (节点 instanceof 参数列表 参数列表) {
            遍历参数列表(监听器, 参数列表);
        } else if (节点 instanceof 变量定义 变量定义) {
            遍历变量定义(监听器, 变量定义);
        } else if (节点 instanceof 指针定义 指针定义) {
            遍历指针定义(监听器, 指针定义);
        } else if (节点 instanceof 方法定义 方法定义) {
            遍历方法定义(监听器, 方法定义);
        } else if (节点 instanceof 标识符 标识符) {
            遍历标识符(监听器, 标识符);
        } else if (节点 instanceof 父类 父类) {
            遍历父类(监听器, 父类);
        } else if (节点 instanceof 类型引用 类型引用) {
            遍历类型引用(监听器, 类型引用);
        } else if (节点 instanceof 类定义 类定义) {
            遍历类定义(监听器, 类定义);
        } else if (节点 instanceof 编译单元 编译单元) {
            遍历编译单元(监听器, 编译单元);
        } else if (节点 instanceof 表达式列表 表达式列表) {
            遍历表达式列表(监听器, 表达式列表);
        }

        // 后缀表达式
        else if (节点 instanceof 成员访问表达式 成员访问表达式) {
            遍历成员访问表达式(监听器, 成员访问表达式);
        } else if (节点 instanceof 方法调用表达式 方法调用表达式) {
            遍历方法调用表达式(监听器, 方法调用表达式);
        }

        // 字面量
        else if (节点 instanceof 字符型字面量 字符型字面量) {
            遍历字符型字面量(监听器, 字符型字面量);
        } else if (节点 instanceof 整数型字面量 整数型字面量) {
            遍历整数型字面量(监听器, 整数型字面量);
        } else if (节点 instanceof 浮点型字面量 浮点型字面量) {
            遍历浮点型字面量(监听器, 浮点型字面量);
        } else if (节点 instanceof 逻辑型字面量 逻辑型字面量) {
            遍历逻辑型字面量(监听器, 逻辑型字面量);
        }

        // 表达式类
        else if (节点 instanceof 关系表达式 关系运算表达式) {
            遍历关系表达式(监听器, 关系运算表达式);
        } else if (节点 instanceof 匹值表达式 匹值运算表达式) {
            遍历匹值表达式(监听器, 匹值运算表达式);
        } else if (节点 instanceof 取反表达式 取反表达式) {
            遍历取反表达式(监听器, 取反表达式);
        } else if (节点 instanceof 取地址表达式 取地址表达式) {
            遍历取地址表达式(监听器, 取地址表达式);
        } else if (节点 instanceof 取负表达式 取负表达式) {
            遍历取负表达式(监听器, 取负表达式);
        } else if (节点 instanceof 算术表达式 算术表达式) {
            遍历算术表达式(监听器, 算术表达式);
        } else if (节点 instanceof 解引用表达式 解引用表达式) {
            遍历解引用表达式(监听器, 解引用表达式);
        }

        // 语句类
        else if (节点 instanceof 条件语句 条件语句) {
            遍历条件语句(监听器, 条件语句);
        } else if (节点 instanceof 赋值语句 赋值语句) {
            遍历赋值语句(监听器, 赋值语句);
        } else if (节点 instanceof 返回语句 返回语句) {
            遍历返回语句(监听器, 返回语句);
        }

        监听器.离开抽象语法树(节点);
    }


    private void 遍历代码块(抽象语法树基础监听器 监听器, 代码块 节点) {
        监听器.进入代码块(节点);

        if (节点.语句 != null) {
            for (var 语句 : 节点.语句) {
                遍历(监听器, 语句);
            }
        }

        监听器.进入代码块(节点);
    }

    private void 遍历参数列表(抽象语法树基础监听器 监听器, 参数列表 节点) {
        监听器.进入参数列表(节点);

        if (节点.参数 != null) {
            for (var 参数 : 节点.参数) {
                遍历(监听器, 参数);
            }
        }

        监听器.离开参数列表(节点);
    }

    private void 遍历变量定义(抽象语法树基础监听器 监听器, 变量定义 节点) {
        监听器.进入变量定义(节点);

        遍历(监听器, 节点.类型);
        遍历(监听器, 节点.初始值);

        监听器.离开变量定义(节点);
    }

    private void 遍历指针定义(抽象语法树基础监听器 监听器, 指针定义 节点) {
        监听器.进入指针定义(节点);

        遍历(监听器, 节点.类型);
        遍历(监听器, 节点.初始值);

        监听器.离开指针定义(节点);
    }

    private void 遍历方法定义(抽象语法树基础监听器 监听器, 方法定义 节点) {
        监听器.进入方法定义(节点);
        遍历(监听器, 节点.返回值类型);
        遍历(监听器, 节点.参数列表);
        遍历(监听器, 节点.代码块);
        监听器.离开方法定义(节点);
    }

    private void 遍历标识符(抽象语法树基础监听器 监听器, 标识符 节点) {
        监听器.进入标识符(节点);
        监听器.离开标识符(节点);
    }

    private void 遍历父类(抽象语法树基础监听器 监听器, 父类 节点) {
        监听器.进入父类(节点);
        监听器.离开父类(节点);
    }

    private void 遍历类型引用(抽象语法树基础监听器 监听器, 类型引用 节点) {
        监听器.进入类型引用(节点);
        监听器.离开类型引用(节点);
    }

    private void 遍历类定义(抽象语法树基础监听器 监听器, 类定义 节点) {
        监听器.进入类定义(节点);
        遍历(监听器, 节点.父类);

        if (节点.成员 != null) {
            for (var 成员 : 节点.成员) {
                遍历(监听器, 成员);
            }
        }

        监听器.离开类定义(节点);
    }

    private void 遍历编译单元(抽象语法树基础监听器 监听器, 编译单元 节点) {
        监听器.进入编译单元(节点);

        if (节点.定义 != null) {
            for (var 定义 : 节点.定义) {
                遍历(监听器, 定义);
            }
        }

        监听器.离开编译单元(节点);
    }

    private void 遍历表达式列表(抽象语法树基础监听器 监听器, 表达式列表 节点) {
        监听器.进入表达式列表(节点);

        if (节点.表达式 != null) {
            for (var 表达式 : 节点.表达式) {
                遍历(监听器, 表达式);
            }
        }

        监听器.离开表达式列表(节点);
    }


    // 后缀表达式

    private void 遍历成员访问表达式(抽象语法树基础监听器 监听器, 成员访问表达式 节点) {
        监听器.进入成员访问表达式(节点);
        遍历(监听器, 节点.对象);
        监听器.离开成员访问表达式(节点);
    }

    private void 遍历方法调用表达式(抽象语法树基础监听器 监听器, 方法调用表达式 节点) {
        监听器.进入方法调用表达式(节点);
        遍历(监听器, 节点.方法);
        遍历(监听器, 节点.参数);
        监听器.离开方法调用表达式(节点);
    }

    // 字面量类

    private void 遍历字符型字面量(抽象语法树基础监听器 监听器, 字符型字面量 节点) {
        监听器.进入字符型字面量(节点);
        监听器.离开字符型字面量(节点);
    }

    private void 遍历整数型字面量(抽象语法树基础监听器 监听器, 整数型字面量 节点) {
        监听器.进入整数型字面量(节点);
        监听器.离开整数型字面量(节点);
    }

    private void 遍历浮点型字面量(抽象语法树基础监听器 监听器, 浮点型字面量 节点) {
        监听器.进入浮点型字面量(节点);
        监听器.离开浮点型字面量(节点);
    }

    private void 遍历逻辑型字面量(抽象语法树基础监听器 监听器, 逻辑型字面量 节点) {
        监听器.进入逻辑型字面量(节点);
        监听器.离开逻辑型字面量(节点);
    }


    // 表达式类

    private void 遍历关系表达式(抽象语法树基础监听器 监听器, 关系表达式 节点) {
        监听器.进入关系表达式(节点);
        遍历(监听器, 节点.左值);
        遍历(监听器, 节点.右值);
        监听器.离开关系表达式(节点);
    }

    private void 遍历匹值表达式(抽象语法树基础监听器 监听器, 匹值表达式 节点) {
        监听器.进入匹值表达式(节点);
        遍历(监听器, 节点.左值);
        遍历(监听器, 节点.右值);
        监听器.离开匹值表达式(节点);
    }

    private void 遍历取反表达式(抽象语法树基础监听器 监听器, 取反表达式 节点) {
        监听器.进入取反表达式(节点);
        遍历(监听器, 节点.表达式);
        监听器.离开取反表达式(节点);
    }

    private void 遍历取地址表达式(抽象语法树基础监听器 监听器, 取地址表达式 节点) {
        监听器.进入取地址表达式(节点);
        遍历(监听器, 节点.表达式);
        监听器.离开取地址表达式(节点);
    }

    private void 遍历取负表达式(抽象语法树基础监听器 监听器, 取负表达式 节点) {
        监听器.进入取负表达式(节点);
        遍历(监听器, 节点.表达式);
        监听器.离开取负表达式(节点);
    }

    private void 遍历算术表达式(抽象语法树基础监听器 监听器, 算术表达式 节点) {
        监听器.进入算术表达式(节点);
        遍历(监听器, 节点.左值);
        遍历(监听器, 节点.右值);
        监听器.离开算术表达式(节点);
    }

    private void 遍历解引用表达式(抽象语法树基础监听器 监听器, 解引用表达式 节点) {
        监听器.进入解引用表达式(节点);
        遍历(监听器, 节点.表达式);
        监听器.离开解引用表达式(节点);
    }

    // 语句类

    private void 遍历条件语句(抽象语法树基础监听器 监听器, 条件语句 节点) {
        监听器.进入条件语句(节点);
        遍历(监听器, 节点.条件);
        遍历(监听器, 节点.真值语句);
        遍历(监听器, 节点.假值语句);
        监听器.离开条件语句(节点);
    }

    private void 遍历赋值语句(抽象语法树基础监听器 监听器, 赋值语句 节点) {
        监听器.进入赋值语句(节点);
        遍历(监听器, 节点.左值);
        遍历(监听器, 节点.右值);
        监听器.离开赋值语句(节点);
    }

    private void 遍历返回语句(抽象语法树基础监听器 监听器, 返回语句 节点) {
        监听器.进入返回语句(节点);
        遍历(监听器, 节点.返回值);
        监听器.离开返回语句(节点);
    }
}
